#include "config.h"

#include "ms2lstat.h"

static ecm_strlist_t	files;

#ifdef MSM_DEBUG
ecm_dbg_t	ms2lstat_dbg;
#endif

static void
usage(void)
{
	ecm_fprintf(ecm_stderr,
"Usage: ms2lstat [ <options> ] <log files>...\n"
" Options:\n"
"   -h: help\n"
"   -q: quiet mode\n"
"   -c <confpath>: configuration path\n"
"   -m <modpath>: module path\n"
"   -x: stop on error\n"
"   -X: don't display log error\n"
"   -l <logbase>: log base path\n"
"   -L: logging with no timestamp suffix\n"
"   -a <interarrival time>: stat only with designated interarrival time\n"
"   -e <media id>: stat only with designated media id\n"
"   -E <rank>: stat only with medias higher than designated rank\n"
#ifdef MSM_DEBUG
"   -d <dbgset>: debug set\n"
"      a: all\n"
"      n: normal log\n"
"      f: forward log\n"
"      b: forward log\n"
#endif
	);
}

static void
signal_handler(ecm_signo_t signo)
{
	switch (signo) {
	case ECM_SIGINT:
	case ECM_SIGTERM:
		ECMVERBOSE("Receive termination signal. Trying to exit!");
		///TODO going_to_shutdown = ECM_TRUE;
		break;
	default:
		break;
	}
}

static void
setup_files(int argc, char *argv[])
{
	int	i;

	files = ecm_strlist_create(ECM_FALSE);
	for (i = ecm_optind; i < argc; i++) {
		char	*file = argv[i];

		if (!ecm_access(file, ECM_R_OK)) {
			ERR("%s: file does not exist", file);
			ecm_exit(1);
		}
		ecm_strlist_add(files, ecm_strdup(file));
	}
	if (ecm_strlist_count(files) == 0) {
		usage();
		ecm_exit(1);
	}
}

#ifdef MSM_DEBUG

static ECMBOOL
parse_debugset(const char *str_dbgset)
{
	ecm_uint32	dbgset = 0;
	const char	*p = str_dbgset;

	while (*p) {
		switch (*p) {
		case 'a':
			dbgset = DBG_ALL;
			break;
		case 'n':
			dbgset |= DBG_NORMAL_LOG;
			break;
		case 'f':
			dbgset |= DBG_FORWARD_LOG;
			break;
		case 'b':
			dbgset |= DBG_BACKWARD_LOG;
			break;
		default:
			return ECM_FALSE;
		}
		p++;
	}

	ecm_set_debugset(ms2lstat_dbg, dbgset);
	return ECM_TRUE;
}

#endif

static void
parse_args_pre(int argc, char *argv[])
{
	int	c;

	while ((c = ecm_getopt(argc, argv, "hqm:xXd:l:La:e:E:c:")) != -1) {
		switch(c) {
		case 'c':
			confpath = ecm_strdup(ecm_optarg);
			break;
		default:
			break;
		}
	}
	ecm_getopt_clear();
}

static void
parse_args(int argc, char *argv[])
{
	int	c;

	while ((c = ecm_getopt(argc, argv, "hqm:xXd:l:La:e:E:c:")) != -1) {
		switch(c) {
		case 'h':
			usage();
			ecm_exit(0);
		case 'c':
			break;
		case 'q':
			ecm_set_verbose_mode(ECM_FALSE);
			break;
		case 'm':
			lparser_modpath = ecm_strdup(ecm_optarg);
			break;
		case 'x':
			stop_on_error = ECM_TRUE;
			break;
		case 'X':
			suppress_display_error = ECM_TRUE;
			break;
		case 'l':
			logbase = ecm_strdup(ecm_optarg);
			break;
		case 'L':
			no_suffix_logging = ECM_TRUE;
			break;
		case 'a':
			if (ecm_sscanf(ecm_optarg, "%d", &stat_iatime) != 1) {
				ERR("%s: invalid interarrival time", ecm_optarg);
				ecm_exit(1);
			}
			break;
		case 'e':
			if (ecm_sscanf(ecm_optarg, "%u", &stat_mid) != 1) {
				ERR("%s: invalid media id", ecm_optarg);
				ecm_exit(1);
			}
			break;
		case 'E':
			if (ecm_sscanf(ecm_optarg, "%u", &stat_media_rank) != 1) {
				ERR("%s: invalid media rank", ecm_optarg);
				ecm_exit(1);
			}
			break;
#ifdef MSM_DEBUG
		case 'd':
			if (!parse_debugset(ecm_optarg)) {
				ERR("invalid debugset");
				ecm_exit(1);
			}
			break;
#endif
		default:
			usage();
			ecm_exit(1);
		}
	}

	if (ecm_empty_str(lparser_modpath)) {
		ERR("module required");
		ecm_exit(1);
	}
	setup_files(argc, argv);
}

static ECMBOOL
init_ms2lstat_pre(void)
{
	if (!init_lstatconf()) {
		ERR("cannot load configuration");
		return ECM_FALSE;
	}
	return ECM_TRUE;
}

static ECMBOOL
init_ms2lstat_post(void)
{
	if (!init_mod()) {
		ERR("cannot initialize module");
		return ECM_FALSE;
	}
	if (!init_media()) {
		ERR("cannot initialize media");
		return ECM_FALSE;
	}
	if (!init_client()) {
		ERR("cannot initialize client");
		return ECM_FALSE;
	}
	if (!init_player()) {
		ERR("cannot initialize player");
		return ECM_FALSE;
	}
	if (!init_session()) {
		ERR("cannot initialize session");
		return ECM_FALSE;
	}
	if (!init_arrival()) {
		ERR("cannot initialize arrival");
		return ECM_FALSE;
	}
	return ECM_TRUE;
}

int
main(int argc, char *argv[])
{
	msl_initialize();

	ecm_set_output_file(ecm_stderr);
	ecm_set_verbose_mode(ECM_TRUE);

	ecm_signal(ECM_SIGINT, signal_handler);
	ecm_signal(ECM_SIGTERM, signal_handler);

#ifdef ECM_DEBUG
	ms2lstat_dbg = ecm_create_dbg();
#endif

	parse_args_pre(argc, argv);

	if (!init_ms2lstat_pre())
		return 1;

	parse_args(argc, argv);

	if (!init_ms2lstat_post())
		return 1;

	if (!parse_logs(files)) {
		ERR("cannot parse logs");
		return 2;
	}

	report_result();

	return 0;
}
